#!/usr/local/bin/python2.7

import pickle, shutil

from conversionlog import *
from constants import *

class DocCrawler(object):
    def __init__(self):
        self._pile_root = Constants.pile_root # raw doc/docx pile
        self._db_root = Constants.db_root # (converted to) docx only pile

        self._log_filepath = Constants.logs_dir
        self._log_filename = 'doc-log.pickle'
        self._doc_log = None
        self._curr_log_entry = LogEntry()

        self._curr_filepath = ''
        self._src_path = ''
        self._dst_path = ''

        self._util_path=os.path.join(Constants.wordconv_path,'Wordconv.exe')
        self._util_path = self._normalizePath(self._util_path)
        poo, self._util_path = os.path.splitdrive(self._util_path)

    def run(self):
        os.chdir(self._pile_root)
        self._loadLog()
        self._beginCrawling()
        self.saveLog()

    def _loadLog(self):
        full_path = os.path.join(self._log_filepath, self._log_filename)
        full_path = self._normalizePath(full_path)

        if not os.path.isfile(full_path):
            self._doc_log = ConversionLog()
        else:
            with open(full_path, 'r') as log:
                self._doc_log = pickle.load(log)

    def _beginCrawling(self):
        for root, dirs, files in os.walk('.'):
            for name in files:
                name=self._normalizePath(name)
                self._curr_filepath = os.path.join(root, name)
                self._buildTransferPaths()

                self._curr_log_entry.src = self._curr_filepath
                self._curr_log_entry.src_abs = self._src_path

                base, ext = os.path.splitext(name)
                if self._outOfDate():
                    if ext == '.docx':
                        self._transferDocx()
                    elif ext == '.doc':
                        self._convertFile()

    def _outOfDate(self):
        if not os.path.isfile(self._dst_path):
            return True

    def _normalizePath(self, path):
        base, ext = os.path.splitext(path)
        path = base + ext.lower()
        path = os.path.normpath(path)

        return path

    def _buildTransferPaths(self):
        self._src_path = os.path.join(self._pile_root, \
                                      self._curr_filepath)

        base, ext = os.path.splitext(self._curr_filepath)
        self._dst_path = os.path.join(self._db_root, base + '.docx')

        self._src_path = self._normalizePath(self._src_path)
        self._dst_path = self._normalizePath(self._dst_path)

        if not os.path.exists(os.path.dirname(self._dst_path)):
            os.makedirs(os.path.dirname(self._dst_path))

    def _transferDocx(self):
        try:
            shutil.copy(self._src_path, self._dst_path)
        except Exception as err:
            print err
            self._curr_log_entry.addError(err)
        else:
            self._completeLogEntry()

        self._writeLog()

    def _convertFile(self):
        mycmd = self._makeConvertCommand()

        try:
            os.system(mycmd)
        except Exception as err:
            print err
            self._curr_log_entry.addError(err)
        else:
            self._completeLogEntry()

        self._writeLog()

    def _completeLogEntry(self):
        self._curr_log_entry.parsed_successfully = True
        self._curr_log_entry.dst = self._dst_path
        self._curr_log_entry.time = os.stat(self._src_path).st_mtime

    def _makeConvertCommand(self):
        drive, src_path = os.path.splitdrive(self._src_path)
        drive, dst_path = os.path.splitdrive(self._dst_path)

        mycmd = '' + self._util_path + ' -oice -nme '
        mycmd += '\"' + src_path + '\" '
        mycmd += '\"' + dst_path + '\"'

        return mycmd

    def _writeLog(self):
        self._doc_log.addEntry(self._curr_log_entry)
        self._curr_log_entry = LogEntry()

    def saveLog(self):
        if self._doc_log is None:
            return

        full_path = os.path.join(self._log_filepath, self._log_filename)
        full_path = self._normalizePath(full_path)

        with open(full_path, 'w') as myfile:
            pickle.dump(self._doc_log, myfile)

        base, ext = os.path.splitext(full_path)
        rst_path = base + '.rst'

        with open(rst_path, 'w') as myfile:
            myfile.write(self._doc_log.rst)

    def getPileRoot(self):
        return self._pile_root
    def setPileRoot(self, val):
        self._pile_root = val
    pile_root = property(getPileRoot, setPileRoot)

    def getLogFilepath(self):
        return self._log_filepath
    def setLogFilepath(self, val):
        self._log_filepath = val
    log_filepath = property(getLogFilepath, setLogFilepath)

